package com.kifas.controller;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import javax.ws.rs.Consumes;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.UriInfo;
import javax.xml.bind.JAXBElement;

import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;

import com.kifas.entity.BarangEntity;
import com.kifas.entity.GudangEntity;
import com.kifas.entity.JenisBarangEntity;
import com.kifas.entity.PengirimanDetailEntity;
import com.kifas.entity.PengirimanEntity;
import com.kifas.entity.PenjualanDetailEntity;
import com.kifas.entity.PenjualanEntity;
import com.kifas.model.xml.BarangModel;
import com.kifas.model.xml.GudangModel;
import com.kifas.model.xml.JenisBarangModel;
import com.kifas.model.xml.PengirimanDetailModel;
import com.kifas.model.xml.PengirimanModel;
import com.kifas.model.xml.PersistStatus;
import com.kifas.model.xml.SatuanModel;
import com.kifas.service.EntityServiceManager;

@Component
@Scope("prototype")
@Path("/Pengirimans")
public class PengirimanController {

	private static Logger log = Logger.getLogger(PengirimanController.class);
	@Context
	UriInfo uriInfo;
	@Autowired
	private EntityServiceManager entityManager;

	@POST
	@Consumes(MediaType.APPLICATION_XML)
	@Produces(MediaType.APPLICATION_XML)
	public PersistStatus persist(JAXBElement<PengirimanModel> xml) {
		PengirimanModel model = xml.getValue();
		Set<PengirimanDetailEntity> pengirimanDetailEntities = new HashSet<PengirimanDetailEntity>();
		log.debug("pengiriman detail found : " + model.getPengirimanDetails().size());
		PenjualanEntity penjualan = entityManager.getPenjualan(model.getIdPenjualan());
		PengirimanEntity previousPengiriman = entityManager.getLatestPengirimanByIdPenjualan(model.getIdPenjualan());
		for (PengirimanDetailModel detail : model.getPengirimanDetails()) {
			log.debug("id barang : " + detail.getBarang().getIdBarang());
			int sisaKirim = 0;
			BarangEntity barangEntity = entityManager.getBarang(detail.getBarang().getIdBarang());
			GudangEntity gudangEntity = entityManager.getGudang(detail.getGudang().getIdMasterGudang());
			PengirimanDetailEntity pengirimanDetailEntity = new PengirimanDetailEntity();
			pengirimanDetailEntity.setIdDetailPengiriman(null);
			pengirimanDetailEntity.setBarang(barangEntity);
			pengirimanDetailEntity.setGudang(gudangEntity);
			pengirimanDetailEntity.setQty(detail.getQty());
			pengirimanDetailEntity.setBulanKadaluarsa(detail.getBulanKadaluarsa());
			pengirimanDetailEntity.setCreatedBy(detail.getCreatedBy());
			pengirimanDetailEntity.setCreatedDate(detail.getCreatedDate());
			if(previousPengiriman != null) {
				for(PengirimanDetailEntity previousPengirimanDetail : previousPengiriman.getPengirimanDetails()) {
					if(barangEntity.getIdBarang() == previousPengirimanDetail.getBarang().getIdBarang()) {
						sisaKirim = previousPengirimanDetail.getSisaKirim() - detail.getQty();
					}
				}
			} else {
				for(PenjualanDetailEntity penjualanDetail : penjualan.getPenjualanDetails()) {
					if(barangEntity.getIdBarang() == penjualanDetail.getBarang().getIdBarang()) {
						sisaKirim = penjualanDetail.getQty().intValue() - detail.getQty();
					}
				}
			}

			pengirimanDetailEntity.setSisaKirim(sisaKirim);
			pengirimanDetailEntities.add(pengirimanDetailEntity);
		}
		PengirimanEntity pengirimanEntity = new PengirimanEntity();
		pengirimanEntity.setIdPengiriman(null);
		pengirimanEntity.setNoPengiriman(model.getNoPengiriman());
		pengirimanEntity.setIdPenjualan(model.getIdPenjualan());
		pengirimanEntity.setIdJenisEkspedisi(model.getIdJenisEkspedisi());
		pengirimanEntity.setTanggalDo(model.getTanggalDo());
		pengirimanEntity.setTanggalKirim(model.getTanggalKirim());
		pengirimanEntity.setTanggalTerima(model.getTanggalTerima());
		pengirimanEntity.setKeterangan(model.getKeterangan());
		pengirimanEntity.setNoKendaraan(model.getNoKendaraan());
		pengirimanEntity.setNoSuratJalan(model.getNoSuratJalan());
		pengirimanEntity.setPengirimanDetails(pengirimanDetailEntities);
		pengirimanEntity.setCreatedBy(model.getCreatedBy());
		pengirimanEntity.setCreatedDate(model.getCreatedDate());

		for (PengirimanDetailEntity pengirimanDetailEntity : pengirimanDetailEntities) {
			log.info("add pengiriman in detail");
			pengirimanDetailEntity.setPengiriman(pengirimanEntity);
		}
		try {
			entityManager.persist(pengirimanEntity);
		} catch (Exception e) {
			log.error("error persist pengiriman", e);
			return new PersistStatus("PengirimanEntity", "failed");
		}
		return new PersistStatus("PengirimanEntity", "success");
	}

	@GET
	@Produces(MediaType.TEXT_XML)
	public List<PengirimanModel> getPengirimans() {
		return transformList(entityManager.getPengirimans());
	}

	@GET
	@Path("Unreceived")
	@Produces(MediaType.TEXT_XML)
	public List<PengirimanModel> getUnreceievedPengirimans() {
		return transformList(entityManager.getUnreceivedPengirimans());
	}

	@GET
	@Path("Received")
	@Produces(MediaType.TEXT_XML)
	public List<PengirimanModel> getReceivedPengirimans() {
		return transformList(entityManager.getReceivedPengirimans());
	}

	@GET
	@Produces(MediaType.TEXT_XML)
	@Path("Penjualan/{id}")
	public List<PengirimanModel> getPengirimansByPenjualan(@PathParam("id") Long penjualanId) {
		List<PengirimanEntity> pengirimanEntities = entityManager.getPengirimanByIdPenjualan(penjualanId);
		List<PengirimanModel> pengirimanModels = new ArrayList<PengirimanModel>();
		Long idPengiriman = null;
		for (PengirimanEntity pengirimanEntity : pengirimanEntities) {
			if (idPengiriman != pengirimanEntity.getIdPengiriman()) {
				PengirimanModel model = new PengirimanModel();
				model.setIdPengiriman(pengirimanEntity.getIdPengiriman());
				model.setIdJenisEkspedisi(pengirimanEntity.getIdJenisEkspedisi());
				model.setIdPengiriman(pengirimanEntity.getIdPengiriman());
				model.setKeterangan(pengirimanEntity.getKeterangan());
				model.setNoKendaraan(pengirimanEntity.getNoKendaraan());
				model.setNoPengiriman(pengirimanEntity.getNoPengiriman());
				model.setNoSuratJalan(pengirimanEntity.getNoSuratJalan());
				Set<PengirimanDetailEntity> pengirimanDetailEntities = pengirimanEntity.getPengirimanDetails();
				Set<PengirimanDetailModel> pengirimanDetailModels = new HashSet<PengirimanDetailModel>();
				for (PengirimanDetailEntity pengirimanDetailEntity : pengirimanDetailEntities) {
					PengirimanDetailModel detailModel = new PengirimanDetailModel();
					detailModel.setIdDetailPengiriman(pengirimanDetailEntity.getIdDetailPengiriman());
					BarangEntity barangEntity = pengirimanDetailEntity.getBarang();
					JenisBarangEntity jenisBarangEntity = barangEntity.getJenisBarang();
					JenisBarangModel jenisBarangModel = new JenisBarangModel(jenisBarangEntity.getIdJenisBarang(), jenisBarangEntity.getJenis(),
							jenisBarangEntity.getCreatedBy());
					SatuanModel satuanModel = new SatuanModel(barangEntity.getSatuan().getIdSatuan(), barangEntity.getSatuan().getSatuan(),
							barangEntity.getCreatedBy());
					BarangModel barangModel = new BarangModel(barangEntity.getIdBarang(), barangEntity.getKdBarang(), jenisBarangModel, satuanModel,
							barangEntity.getNama(), barangEntity.getHargaBeli(), barangEntity.getHargaJual(), barangEntity.getCreatedBy());
					detailModel.setBarang(barangModel);
					GudangEntity gudang = pengirimanDetailEntity.getGudang();
					GudangModel gudangModel = new GudangModel(gudang.getIdGudang(), gudang.getNamaGudang(), gudang.getLokasi(), gudang.getKapasitas(),
							gudang.getPetugas(), gudang.getAlamat(), gudang.getKode(), gudang.getNotelp(), gudang.getTgl_jth_tempo(), gudang.getCreatedBy());
					detailModel.setGudang(gudangModel);
					detailModel.setBulanKadaluarsa(pengirimanDetailEntity.getBulanKadaluarsa());
					detailModel.setQty(pengirimanDetailEntity.getQty());
					pengirimanDetailModels.add(detailModel);
				}
				model.setPengirimanDetails(pengirimanDetailModels);
				model.setTanggalDo(pengirimanEntity.getTanggalDo());
				model.setTanggalKirim(pengirimanEntity.getTanggalKirim());
				model.setTanggalTerima(pengirimanEntity.getTanggalTerima());

				pengirimanModels.add(model);

				idPengiriman = pengirimanEntity.getIdPengiriman();
			}
		}
		return pengirimanModels;
	}

	private List<PengirimanModel> transformList(List<PengirimanEntity> pengirimanEntities) {
		List<PengirimanModel> pengirimanModels = new ArrayList<PengirimanModel>();
		for (PengirimanEntity pengirimanEntity : pengirimanEntities) {
			pengirimanModels.add(transform(pengirimanEntity));
		}
		return pengirimanModels;
	}

	private PengirimanModel transform(PengirimanEntity pengirimanEntity) {
		PengirimanModel model = new PengirimanModel();
		model.setIdPengiriman(pengirimanEntity.getIdPengiriman());
		model.setIdJenisEkspedisi(pengirimanEntity.getIdJenisEkspedisi());
		model.setIdPengiriman(pengirimanEntity.getIdPengiriman());
		model.setKeterangan(pengirimanEntity.getKeterangan());
		model.setNoKendaraan(pengirimanEntity.getNoKendaraan());
		model.setNoPengiriman(pengirimanEntity.getNoPengiriman());
		model.setNoSuratJalan(pengirimanEntity.getNoSuratJalan());
		model.setCreatedBy(pengirimanEntity.getCreatedBy());
		model.setCreatedDate(pengirimanEntity.getCreatedDate());
		Set<PengirimanDetailEntity> pengirimanDetailEntities = pengirimanEntity.getPengirimanDetails();
		Set<PengirimanDetailModel> pengirimanDetailModels = new HashSet<PengirimanDetailModel>();
		for (PengirimanDetailEntity pengirimanDetailEntity : pengirimanDetailEntities) {
			PengirimanDetailModel detailModel = new PengirimanDetailModel();
			detailModel.setIdDetailPengiriman(pengirimanDetailEntity.getIdDetailPengiriman());
			BarangEntity barangEntity = pengirimanDetailEntity.getBarang();
			JenisBarangEntity jenisBarangEntity = barangEntity.getJenisBarang();
			JenisBarangModel jenisBarangModel = new JenisBarangModel(jenisBarangEntity.getIdJenisBarang(), jenisBarangEntity.getJenis(),
					jenisBarangEntity.getCreatedBy());
			SatuanModel satuanModel = new SatuanModel(barangEntity.getSatuan().getIdSatuan(), barangEntity.getSatuan().getSatuan(), barangEntity.getCreatedBy());
			BarangModel barangModel = new BarangModel(barangEntity.getIdBarang(), barangEntity.getKdBarang(), jenisBarangModel, satuanModel,
					barangEntity.getNama(), barangEntity.getHargaBeli(), barangEntity.getHargaJual(), barangEntity.getCreatedBy());
			detailModel.setBarang(barangModel);
			GudangEntity gudangEntity = pengirimanDetailEntity.getGudang();
			GudangModel gudangModel = new GudangModel(gudangEntity.getIdGudang(), gudangEntity.getNamaGudang(), gudangEntity.getLokasi(),
					gudangEntity.getKapasitas(), gudangEntity.getPetugas(), gudangEntity.getAlamat(), gudangEntity.getKode(), gudangEntity.getNotelp(),
					gudangEntity.getTgl_jth_tempo(), gudangEntity.getCreatedBy());
			detailModel.setGudang(gudangModel);
			detailModel.setBulanKadaluarsa(pengirimanDetailEntity.getBulanKadaluarsa());
			detailModel.setQty(pengirimanDetailEntity.getQty());
			detailModel.setSisaKirim(pengirimanDetailEntity.getSisaKirim());
			pengirimanDetailModels.add(detailModel);
		}
		model.setPengirimanDetails(pengirimanDetailModels);
		model.setTanggalDo(pengirimanEntity.getTanggalDo());
		model.setTanggalKirim(pengirimanEntity.getTanggalKirim());
		model.setTanggalTerima(pengirimanEntity.getTanggalTerima());
		model.setCreatedBy(pengirimanEntity.getCreatedBy());
		model.setCreatedDate(pengirimanEntity.getCreatedDate());
		return model;
	}
}
